﻿using AzureStorageMapper.TableStorage;
using AzureStorageMapper.TableStorage.Attributes;
using AzureStorageMapper.TableStorage.Utils;
using NUnit.Framework;
using System;

namespace AzureStorageMapper.Tests.TableStorage.Utils
{
    [TestFixture]
    public class TableFactoryUtilitiesTests
    {
        [SetUp]
        public void Setup()
        {
        }

        [Test]
        public void GetTableInfoTest()
        {
            TableInfo info = TableUtilities.GetTableInfo(typeof(SampleTableModel));

            Assert.AreEqual("SampleTable", info.Name);

            Assert.AreEqual(3, info.Columns.Count);
            Assert.AreEqual("ColumnOne", info.Columns[0].Name);
            Assert.AreEqual(typeof(string), info.Columns[0].ColumnType);

            Assert.AreEqual("Column2", info.Columns[1].Name);
            Assert.AreEqual(typeof(int), info.Columns[1].ColumnType);

            Assert.AreEqual("Column4", info.Columns[2].Name);
            Assert.AreEqual(typeof(int), info.Columns[2].ColumnType);
        }

        [Test]
        public void GetTableInfoTest_DefaultName()
        {
            TableInfo info = TableUtilities.GetTableInfo(typeof(SampleTableModel2));

            Assert.AreEqual("SampleTableModel2", info.Name);

            Assert.AreEqual(3, info.Columns.Count);
            Assert.AreEqual("ColumnOne", info.Columns[0].Name);
            Assert.AreEqual(typeof(string), info.Columns[0].ColumnType);

            Assert.AreEqual("Column2", info.Columns[1].Name);
            Assert.AreEqual(typeof(int), info.Columns[1].ColumnType);

            Assert.AreEqual("Column4", info.Columns[2].Name);
            Assert.AreEqual(typeof(int), info.Columns[2].ColumnType);
        }

        [Test]
        public void GetEntryInfoTest()
        {

            SampleTableModel stm = new SampleTableModel("DefaultPartition", Guid.NewGuid().ToString());
            stm.ColumnOne = "I am column one";
            stm.ColumnTwo = 2;
            stm.ColumnFour = 4;

            EntityInfo eInfo = TableUtilities.GetEntityInfo(stm);

            Assert.AreEqual("SampleTable", eInfo.TableName);
            Assert.AreEqual(stm.PartitionKey, eInfo.PartitionKey);
            Assert.AreEqual(stm.RowKey, eInfo.RowKey);
            
            Assert.AreEqual(3, eInfo.Columns.Count);

            foreach (var item in eInfo.Columns)
            {
                if (item.Key.Name.Equals("ColumnOne"))
                {
                    Assert.AreEqual("I am column one", item.Value);
                    Assert.AreEqual(typeof(string), item.Key.ColumnType);
                }
                else if (item.Key.Name.Equals("Column2"))
                {
                    Assert.AreEqual(2, item.Value);
                    Assert.AreEqual(typeof(int), item.Key.ColumnType);
                }
                else if (item.Key.Name.Equals("Column4"))
                {
                    Assert.AreEqual(4, item.Value);
                    Assert.AreEqual(typeof(int), item.Key.ColumnType);
                }
                else
                    Assert.IsTrue(false);
            }
        }
    }

    [TableModel(Name = "SampleTable")]
    internal class SampleTableModel : TableEntity
    {
        [TableColumn]
        public string ColumnOne { get; set; }

        [TableColumn(Name = "Column2")]
        public int ColumnTwo { get; set; }

        private long ColumnThree { get; set; }

        [TableColumn(Name = "Column4", ColumnType = typeof(int))]
        public long ColumnFour { get; set; }

        public SampleTableModel(string partitionKey, string rowKey)
            : base(partitionKey, rowKey)
        {
        }
    }

    [TableModel]
    internal class SampleTableModel2 : TableEntity
    {
        [TableColumn]
        public string ColumnOne { get; set; }

        [TableColumn(Name = "Column2")]
        public int ColumnTwo { get; set; }

        private long ColumnThree { get; set; }

        [TableColumn(Name = "Column4", ColumnType = typeof(int))]
        public long ColumnFour { get; set; }

        public SampleTableModel2(string partitionKey, string rowKey)
            : base(partitionKey, rowKey)
        {
        }
    }
}
